package kr.ac.konkuk.db.quadtree.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import kr.ac.konkuk.db.quadtree.QuadTree;
import kr.ac.konkuk.db.quadtree.RowKey;
import kr.ac.konkuk.db.quadtree.callback.SearchOperator;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;

public class ByteWKTQuadTree implements QuadTree<List<Byte>> {
	private QuadTree<String> qt;
	private String charSet;
	
	public ByteWKTQuadTree(String charSet, QuadTree<Geometry> qt) {
		this.qt = new WKTQuadTree(qt);
		this.charSet = charSet;
	}
	
	public ByteWKTQuadTree(QuadTree<Geometry> qt) {
		this("UTF-8", qt);
	}
	
	public Set<String> insert(RowKey rowKey, List<Byte> item) {
		return qt.insert(rowKey, read(item));
	}

	public Set<String> insert(List<Byte> rowKey, List<Byte> item) {
		return qt.insert(rowKey, read(item));
	}

	public Set<String> search(Envelope searchEnv, SearchOperator operator) {
		return qt.search(searchEnv, operator);
	}

	public boolean remove(RowKey rowKey) {
		return qt.remove(rowKey);
	}

	public boolean remove(List<Byte> rowKey) {
		return qt.remove(rowKey);
	}

	private String read(final List<Byte> item) {
		BufferedReader reader = null;
		
		try {
			reader = new BufferedReader(new InputStreamReader(new InputStream() {
				private Iterator<Byte> it = item.iterator();
				
				public int read() throws IOException {
					if (it.hasNext()) {
						byte b = it.next();
						return b < 0 ? Byte.MAX_VALUE + 1 + b : b;
					} else {
						return -1;
					}
				}
				
			}, charSet));
			return reader.readLine();
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		} catch(IOException e) { 
			throw new RuntimeException(e);
		} finally {
			if (reader != null) {
				try { reader.close(); } catch(IOException e) {}
			}
		}
	}

	@Override
	public Set<String> search(Geometry searchEnv, SearchOperator operator) {
		return qt.search(searchEnv, operator);
	}
}
